udata=load('u.data.txt'); 
movies= readcell("u_item.txt");
u= udata(1:end,1:2);
clear udata;
users = unique(u(:,1)); 
Nu= length(users); 
m=length(movies);
for i=1:m
    movielist(i)=string(movies{i,1});
end
Set= cell(Nu,1);
for n = 1:Nu
    ind = find(u(:,1) == users(n));
    Set{n} = [Set{n} u(ind,2)];
end

J=zeros(Nu); 
K=130; %200 era muito longo e com 100 podia haver alguns erros, foi o número que mais contentou em termos de runtime vs numero de erros
MinHashTable=inf(Nu,K);
for i=1:Nu %cria as Min-Hash
    conjunto=Set{i};
    for j=1:length(conjunto)
        chave=char(conjunto(j));
        h=zeros(1,K);
        for kk=1:K
            chave=[chave num2str(kk)];
            h(kk)=DJB31MA(chave ,127); 
        end
        MinHashTable(i,:)=min([MinHashTable(i,:);h]);
    end
end
for n1=1:Nu %Calcula as distâncias de Jaccard aproximadas
    for n2=n1+1:Nu
        J(n1,n2)= sum(MinHashTable(n1,:)~=MinHashTable(n2,:))/K;
    end
end 
k=1;
SimilarUsers= zeros(1,3); 
for n1= 1:Nu %Guarda numa matriz a distância entre 2 users de forma a que o par só apareça uma vez e não haja pares do tipo (1,1) 
    for n2= n1+1:Nu
            SimilarUsers(k,:)= [users(n1) users(n2) J(n1,n2)];
            k= k+1;
    end
end
k=4; %Shingles
MinHashMovies=inf(m,K);
for i=1:m %cria as Min-Hash
    conj=char(lower(movies{i,1}));
    for j=1:length(conj)-k+1
        chave=conj(j:j+k-1);
        h=zeros(1,K);
        for kk=1:K
            chave=[chave num2str(kk)];
            h(kk)=DJB31MA(chave ,127); 
        end
        MinHashMovies(i,:)=min([MinHashMovies(i,:);h]);
    end
end
save("struct.mat") %guarda o ficheiro com as estruturas